<?php

// @formatter:off
/**
 * @file edit.php
 * @author Alejandro Dario Simi
 * @date $Date: 2014-06-03 03:40:32 +0000 (Tue, 03 Jun 2014) $
 *
 * $Id: edit.php 112 2014-06-03 03:40:32Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/trunk/frontview/actions/rule/tare/edit.php $
 */
// @formatter:on

class ActionControllerRuleTareEdit extends WCActionController {
	//
	// Potected variables.
	/**
	 * @var WCConnection Database pointer shortcut.
	 */
	protected $_db;
	/**
	 * @var string Database tables' prefix shortcut.
	 */
	protected $_dbprefix;
	//
	// Magic methods.
	public function __construct() {
		parent::__construct();
		//
		// Loading shortcuts.
		// @{
		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $this->_db->prefix();
		// @}
	}
	//
	// Public methods.
	public function check() {
		$check = parent::check();

		if($check == WC_HTTPERROR_OK) {
			global $wcProfile;
			global $wcRule;
			global $wcRuleAction;

			if(!$wcProfile->allowedTo(WC_PERM_RULE_EDIT)) {
				global $errno;
				global $error;

				$check = WC_HTTPERROR_FORBIDDEN;
				$errno = $check;
				$error = "You don't have enough priviliges";
			}

			if($check == WC_HTTPERROR_OK && (!$wcRule || !$wcRule->ok())) {
				global $errno;
				global $error;

				$check = WC_HTTPERROR_BAD_REQUEST;
				$errno = $check;
				$error = "Invalid rule";
			}
			if($check == WC_HTTPERROR_OK && (!$wcRuleAction || !$wcRuleAction->ok())) {
				global $errno;
				global $error;

				$check = WC_HTTPERROR_BAD_REQUEST;
				$errno = $check;
				$error = "Invalid rule action";
			}
			if($check == WC_HTTPERROR_OK && ($wcRuleAction->rule()->id() != $wcRule->id())) {
				global $errno;
				global $error;

				$check = WC_HTTPERROR_BAD_REQUEST;
				$errno = $check;
				$error = "Wrong rule action combination";
			}
		}

		return $check;
	}
	//
	// Protected methods.
	protected function editAlso() {
		$editted = false;

		global $wcGroup;
		global $wcRule;
		global $wcRuleAction;

		if($_POST["task"] == "add") {
			if($wcRuleAction->target) {
				$newTagNames = array();
				foreach($_POST["names"] as $tagName) {
					$tagName = trim($tagName);
					if($tagName) {
						$newTagNames[] = $tagName;
					}
				}

				$newTags = array();
				$currentIds = array_keys($wcRuleAction->tagsAlso());
				foreach($newTagNames as $name) {
					$tag = WCTagsHolder::I()->itemByNameInGroup($name, $wcGroup);
					$tag = array_shift($tag);
					//
					// If it is a new tag it creates it.
					if(!$tag) {
						$tag = WCTagsHolder::I()->createInGroup($name, $wcGroup);
					}

					if($tag && $tag->ok() && !in_array($tag->id, $currentIds)) {
						$newTags[$tag->id] = $tag;
					}
				}

				$stmt = null;
				$stmtId = __CLASS__."::".__FUNCTION__."[ADD]";
				if($this->_db->has($stmtId)) {
					$stmt = $this->_db->get($stmtId);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}acts_tare (\n";
					$query .= "                act_rule, act_group, act_action, act_tag, act_also)\n";
					$query .= "        values (:rule, :group, :action, :tag, :also)\n";

					$stmt = $this->_db->prepare($stmtId, $query);
				}

				$tag = WCTagsHolder::I()->itemByNameInGroup($wcRuleAction->target, $wcGroup);
				$tag = array_shift($tag);
				if($tag && $tag->ok()) {
					foreach($newTags as $also) {
						$params = array(
							":rule" => $wcRule->id(),
							":group" => $wcGroup->id,
							":action" => $wcRuleAction->id(),
							":tag" => $tag->id,
							":also" => $also->id
						);

						$stmt->execute($params);
						$editted = true;
					}
				}

				if(!$editted) {
					$this->_manager->status_message = $this->tr("message_nothing_to_do");
				}
			} else {
				$this->_manager->status_message = $this->tr("message_no_target");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		} elseif($_POST["task"] == "remove") {
			$tagIds = $_POST["ids"];

			$badTags = array();
			$currentIds = array_keys($wcRuleAction->tagsAlso());
			foreach($tagIds as $id) {
				$tag = WCTagsHolder::I()->item($id);
				if($tag->ok() && in_array($tag->id, $currentIds)) {
					$badTags[$tag->id] = $tag;
				}
			}

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[REMOVE]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "delete from {$this->_dbprefix}acts_tare\n";
				$query .= "where       act_rule   = :rule\n";
				$query .= " and        act_group  = :group\n";
				$query .= " and        act_action = :action\n";
				$query .= " and        act_also   = :also\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			foreach($badTags as $also) {
				$params = array(
					":rule" => $wcRule->id(),
					":group" => $wcGroup->id,
					":action" => $wcRuleAction->id(),
					":also" => $also->id
				);

				$stmt->execute($params);

				$editted = true;
			}

			if(!$editted) {
				$this->_manager->status_message = $this->tr("message_nothing_to_do");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		}

		return $editted;
	}
	protected function editIf() {
		$editted = false;

		global $wcGroup;
		global $wcRule;
		global $wcRuleAction;

		if($_POST["task"] == "add") {
			if($wcRuleAction->target) {
				$newTagNames = array();
				foreach($_POST["names"] as $tagName) {
					$tagName = trim($tagName);
					if($tagName) {
						$newTagNames[] = $tagName;
					}
				}

				$newTags = array();
				$currentIds = array_keys($wcRuleAction->tagsAlso());
				foreach($newTagNames as $name) {
					$tag = WCTagsHolder::I()->itemByNameInGroup($name, $wcGroup);
					$tag = array_shift($tag);
					//
					// If it is a new tag it creates it.
					if(!$tag) {
						$tag = WCTagsHolder::I()->createInGroup($name, $wcGroup);
					}

					if($tag && $tag->ok() && !in_array($tag->id, $currentIds)) {
						$newTags[$tag->id] = $tag;
					}
				}

				$stmt = null;
				$stmtId = __CLASS__."::".__FUNCTION__."[ADD]";
				if($this->_db->has($stmtId)) {
					$stmt = $this->_db->get($stmtId);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}acts_tare (\n";
					$query .= "                act_rule, act_group, act_action, act_tag, act_also)\n";
					$query .= "        values (:rule, :group, :action, :tag, :also)\n";

					$stmt = $this->_db->prepare($stmtId, $query);
				}

				$tag = WCTagsHolder::I()->itemByNameInGroup($wcRuleAction->target, $wcGroup);
				$tag = array_shift($tag);
				if($tag && $tag->ok()) {
					foreach($newTags as $also) {
						$params = array(
							":rule" => $wcRule->id(),
							":group" => $wcGroup->id,
							":action" => $wcRuleAction->id(),
							":tag" => $tag->id,
							":also" => $also->id
						);

						$stmt->execute($params);
						$editted = true;
					}
				}

				if(!$editted) {
					$this->_manager->status_message = $this->tr("message_nothing_to_do");
				}
			} else {
				$this->_manager->status_message = $this->tr("message_no_target");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		} elseif($_POST["task"] == "remove") {
			$tagIds = $_POST["ids"];

			$badTags = array();
			$currentIds = array_keys($wcRuleAction->tagsAlso());
			foreach($tagIds as $id) {
				$tag = WCTagsHolder::I()->item($id);
				if($tag->ok() && in_array($tag->id, $currentIds)) {
					$badTags[$tag->id] = $tag;
				}
			}

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[REMOVE]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "delete from {$this->_dbprefix}acts_tare\n";
				$query .= "where       act_rule   = :rule\n";
				$query .= " and        act_group  = :group\n";
				$query .= " and        act_action = :action\n";
				$query .= " and        act_also   = :also\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			foreach($badTags as $also) {
				$params = array(
					":rule" => $wcRule->id(),
					":group" => $wcGroup->id,
					":action" => $wcRuleAction->id(),
					":also" => $also->id
				);

				$stmt->execute($params);

				$editted = true;
			}

			if(!$editted) {
				$this->_manager->status_message = $this->tr("message_nothing_to_do");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		}

		return $editted;
	}
	protected function editMerge() {
		$editted = false;

		global $wcGroup;
		global $wcRule;
		global $wcRuleAction;

		if($_POST["task"] == "add") {
			if($wcRuleAction->target) {
				$newTagNames = array();
				foreach($_POST["names"] as $tagName) {
					$tagName = trim($tagName);
					if($tagName) {
						$newTagNames[] = $tagName;
					}
				}

				$newTags = array();
				$currentIds = array_keys($wcRuleAction->tagsAlso());
				foreach($newTagNames as $name) {
					$tag = WCTagsHolder::I()->itemByNameInGroup($name, $wcGroup);
					$tag = array_shift($tag);
					//
					// If it is a new tag it creates it.
					if(!$tag) {
						$tag = WCTagsHolder::I()->createInGroup($name, $wcGroup);
					}

					if($tag && $tag->ok() && !in_array($tag->id, $currentIds)) {
						$newTags[$tag->id] = $tag;
					}
				}

				$stmt = null;
				$stmtId = __CLASS__."::".__FUNCTION__."[ADD]";
				if($this->_db->has($stmtId)) {
					$stmt = $this->_db->get($stmtId);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}acts_tare (\n";
					$query .= "                act_rule, act_group, act_action, act_tag, act_also)\n";
					$query .= "        values (:rule, :group, :action, :tag, :also)\n";

					$stmt = $this->_db->prepare($stmtId, $query);
				}

				$tag = WCTagsHolder::I()->itemByNameInGroup($wcRuleAction->target, $wcGroup);
				$tag = array_shift($tag);
				if($tag && $tag->ok()) {
					foreach($newTags as $also) {
						$params = array(
							":rule" => $wcRule->id(),
							":group" => $wcGroup->id,
							":action" => $wcRuleAction->id(),
							":tag" => $tag->id,
							":also" => $also->id
						);

						$stmt->execute($params);

						$editted = true;
					}
				}

				if(!$editted) {
					$this->_manager->status_message = $this->tr("message_nothing_to_do");
				}
			} else {
				$this->_manager->status_message = $this->tr("message_no_target");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		} elseif($_POST["task"] == "remove") {
			$tagIds = $_POST["ids"];

			$badTags = array();
			$currentIds = array_keys($wcRuleAction->tagsAlso());
			foreach($tagIds as $id) {
				$tag = WCTagsHolder::I()->item($id);
				if($tag->ok() && in_array($tag->id, $currentIds)) {
					$badTags[$tag->id] = $tag;
				}
			}

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[REMOVE]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "delete from {$this->_dbprefix}acts_tare\n";
				$query .= "where       act_rule   = :rule\n";
				$query .= " and        act_group  = :group\n";
				$query .= " and        act_action = :action\n";
				$query .= " and        act_also   = :also\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			foreach($badTags as $also) {
				$params = array(
					":rule" => $wcRule->id(),
					":group" => $wcGroup->id,
					":action" => $wcRuleAction->id(),
					":also" => $also->id
				);

				$stmt->execute($params);

				$editted = true;
			}

			if(!$editted) {
				$this->_manager->status_message = $this->tr("message_nothing_to_do");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		}

		return $editted;
	}
	protected function editPool() {
		$editted = false;

		global $wcGroup;
		global $wcRule;
		global $wcRuleAction;

		if($_POST["task"] == "add") {
			$newTagNames = array();
			foreach($_POST["names"] as $tagName) {
				$tagName = trim($tagName);
				if($tagName) {
					$newTagNames[] = $tagName;
				}
			}

			$newTags = array();
			$currentIds = array_keys($wcRuleAction->tags());
			foreach($newTagNames as $name) {
				$tag = WCTagsHolder::I()->itemByNameInGroup($name, $wcGroup);
				$tag = array_shift($tag);
				//
				// If it is a new tag it creates it.
				if(!$tag) {
					$tag = WCTagsHolder::I()->createInGroup($name, $wcGroup);
				}

				if($tag && $tag->ok() && !in_array($tag->id, $currentIds)) {
					$newTags[$tag->id] = $tag;
				}
			}

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[ADD]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "insert\n";
				$query .= "        into {$this->_dbprefix}acts_tare (\n";
				$query .= "                act_rule, act_group, act_action, act_tag, act_also)\n";
				$query .= "        values (:rule, :group, :action, :tag, 0)\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			foreach($newTags as $tag) {
				$params = array(
					":rule" => $wcRule->id(),
					":group" => $wcGroup->id,
					":action" => $wcRuleAction->id(),
					":tag" => $tag->id
				);

				$stmt->execute($params);

				$editted = true;
			}

			if(!$editted) {
				$this->_manager->status_message = $this->tr("message_nothing_to_do");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		} elseif($_POST["task"] == "remove") {
			$tagIds = $_POST["ids"];

			$badTags = array();
			$currentIds = array_keys($wcRuleAction->tags());
			foreach($tagIds as $id) {
				$tag = WCTagsHolder::I()->item($id);
				if($tag->ok() && in_array($tag->id, $currentIds)) {
					$badTags[$tag->id] = $tag;
				}
			}

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[REMOVE]";
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "delete from {$this->_dbprefix}acts_tare\n";
				$query .= "where       act_rule   = :rule\n";
				$query .= " and        act_group  = :group\n";
				$query .= " and        act_action = :action\n";
				$query .= " and        act_tag    = :tag\n";
				$query .= " and        act_also   = 0\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			foreach($badTags as $tag) {
				$params = array(
					":rule" => $wcRule->id(),
					":group" => $wcGroup->id,
					":action" => $wcRuleAction->id(),
					":tag" => $tag->id,
				);

				$stmt->execute($params);

				$editted = true;
			}

			if(!$editted) {
				$this->_manager->status_message = $this->tr("message_nothing_to_do");
			}

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		}

		return $editted;
	}
	protected function loadInfo() {
		//
		// Loading global pointers.
		global $wcRule;
		global $wcRuleAction;

		foreach(WCViewInfoFactory::LoadInfo($wcRule) as $key => $value) {
			eval("\$this->_manager->info_rule_{$key} = \$value;");
		}
		foreach(WCViewInfoFactory::LoadInterfacesInfo($wcRule) as $key => $value) {
			eval("\$this->_manager->info_rule_{$key} = \$value;");
		}
		WCViewInfoFactory::LoadInfo($wcRuleAction, true);
	}
	protected function resetName() {
		global $wcRuleAction;

		$wcRuleAction->setName(trim($_POST["name"]));
	}
	protected function resetTarget() {
		global $wcGroup;
		global $wcRule;
		global $wcRuleAction;

		$aux = explode(",", $_POST["tag"]);
		$targetName = trim(array_shift($aux));

		$tag = WCTagsHolder::I()->itemByNameInGroup($targetName, $wcGroup);
		$tag = array_shift($tag);
		if($tag && $tag->ok()) {
			$wcRuleAction->target = $tag->name;
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update {$this->_dbprefix}acts_tare\n";
				$query .= "set    act_tag = :tag\n";
				$query .= "where  act_rule   = :rule\n";
				$query .= " and   act_group  = :group\n";
				$query .= " and   act_action = :action\n";

				$stmt = $this->_db->prepare($stmtId, $query);
			}

			$params = array(
				":rule" => $wcRule->id(),
				":group" => $wcGroup->id,
				":action" => $wcRuleAction->id(),
				":tag" => $tag->id,
			);

			$stmt->execute($params);

			$wcRuleAction->setValidPreviews(false);
			$wcRuleAction->reload();
		}
	}
	protected function setTargetInfo($tagName) {
		global $wcGroup;
		$items = WCTagsHolder::I()->itemByNameInGroup($tagName, $wcGroup);
		$item = array_shift($items);

		if($item && $item->ok()) {
			$this->_manager->target_id = $item->id;
		}
		$this->_manager->target = $tagName;
	}
	protected function subRun() {
		$ok = true;
		//
		// Loading global pointers.
		global $wcRule;
		global $wcRuleAction;

		$mode = $wcRuleAction->mode;

		$this->_manager->PATH = "Action Edit: '{$wcRuleAction->name()}' of rule '{$wcRule->name()}'";

		switch($mode) {
			case "POOL":
				$tags = array();
				foreach($wcRuleAction->tags(true) as $tag) {
					$tags[] = array(
						"id" => $tag->id(),
						"name" => $tag->name()
					);
				}
				$this->_manager->tags = $tags;

				break;
			case "ALSO":
				$this->setTargetInfo($wcRuleAction->target);

				$also = array();
				foreach($wcRuleAction->tagsAlso(true) as $tag) {
					$also[] = array(
						"id" => $tag->id(),
						"name" => $tag->name()
					);
				}
				$this->_manager->also = $also;

				break;
			case "IF":
				$this->setTargetInfo($wcRuleAction->target);

				$also = array();
				foreach($wcRuleAction->tagsAlso() as $tag) {
					$also[] = array(
						"id" => $tag->id(),
						"name" => $tag->name()
					);
				}
				$this->_manager->also = $also;

				break;
			case "MERGE":
				$this->setTargetInfo($wcRuleAction->target);

				$also = array();
				foreach($wcRuleAction->tagsAlso() as $tag) {
					$also[] = array(
						"id" => $tag->id(),
						"name" => $tag->name()
					);
				}
				$this->_manager->also = $also;

				break;
			default:
				break;
		}

		$this->loadInfo();

		return $ok;
	}
	protected function subRunPOST() {
		$ok = true;

		global $wcRuleAction;

		if($wcRuleAction->name() != $_POST["name"]) {
			$this->resetName();
		}
		if($wcRuleAction->target != $_POST["tag"]) {
			$this->resetTarget();
		}

		$mode = $wcRuleAction->mode;
		if($mode == $_POST["mode"]) {
			switch($_POST["mode"]) {
				case "ALSO":
					$this->_manager->status = $this->editAlso();
					break;
				case "POOL":
					$this->_manager->status = $this->editPool();
					break;
				case "IF":
					$this->_manager->status = $this->editIf();
					break;
				case "MERGE":
					$this->_manager->status = $this->editMerge();
					break;
				default:
					$this->_manager->status = false;
					$this->_manager->status_message = $this->tr("message_unknown_mode");
					break;
			}
		} else {
			$this->_manager->status = false;
			$this->_manager->status_message = $this->tr("message_unknown_error");
		}

		return $ok;
	}
}
